package com.kania.simpleemail.maillist;

import java.io.IOException;
import java.util.ArrayList;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.internet.MimeUtility;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.kania.simpleemail.R;
import com.kania.simpleemail.Welcome;
import com.kania.simpleemail.composer.ComposerActivity;
import com.kania.simpleemail.core.IMAP;
import com.kania.simpleemail.data.EmailDBHelper;
import com.kania.simpleemail.data.MailData;
import com.kania.simpleemail.mailview.DetailViewFragment;
import com.kania.simpleemail.service.EmailService;

public class MailListActivity extends Activity{
	
	private SharedPreferences accountInfo;
	private final String STRING_ACCOUNT_PREFERENCE_NAME = "account_info";
	private MailListAdapter listAdapter;
	private ArrayAdapter<String> tempAdapter;
	
	private ArrayList<MailData> alMailData;
	private ArrayList<String> tempal;
	
	private ListView lvMailList;
	
	private String sID = "";
	private String sPassword = "";
	private String sHost = "imap.gmail.com"; //TODO ....
	
	private String sErrorMsg = "";
	
	private String sTag = "KANIA_LOG_LIST";
	
	public static final int MSG_REFRESH_LIST = 0;
	public static final int MSG_NOW_FULLSYNC = 1;
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			Bundle data = msg.getData();
			//TODO 여기서 notify
			switch(data.getInt("msgtype")) {
			case MSG_REFRESH_LIST:
				listAdapter.notifyDataSetChanged();
				break;
			case MSG_NOW_FULLSYNC:
				Toast.makeText(MailListActivity.this, "Fullsync task is running now, try after fullsync is finished.", Toast.LENGTH_SHORT).show();
				break;
			}
		}
		
	};
	
	AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			if (!bNowSync) {
				FragmentManager fragmentmanager = getFragmentManager();
				FragmentTransaction fragmentTransaction = fragmentmanager.beginTransaction();
				
				DetailViewFragment detailViewFragment = new DetailViewFragment(folder, alMailData.get(position));
				fragmentTransaction.add(R.id.maillistFragContainer, detailViewFragment);
				fragmentTransaction.addToBackStack(null);
				fragmentTransaction.commit();
			} else {
				android.os.Message msg = android.os.Message.obtain();
				Bundle data = new Bundle();
				data.putInt("msgtype", MSG_NOW_FULLSYNC);
				msg.setData(data);
				mHandler.sendMessage(msg);
//				Toast.makeText(MailListActivity.this, "Fullsync task is running now, try after fullsync is finished.", Toast.LENGTH_SHORT);
			}
		}
	};
	
//	IMAP loginSession;
	FullSyncTask taskFullSync;
	public static boolean bNowSync = false;
	
	IMAP loginSession = null;
	Folder folder = null;
	
	private int nMaxMailNumber = 10; //TODO 이 부분은 추후 setting으로 들어가야 함

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_mail_list);
		accountInfo = this.getSharedPreferences(STRING_ACCOUNT_PREFERENCE_NAME, Activity.MODE_PRIVATE);
//		String sExistAccountList = accountInfo.getString("exist_account", "");
		sID = accountInfo.getString("exist_account", "");
		sPassword = accountInfo.getString("password", "");
		
		//debug
		this.setTitle(sID + " / " + sPassword);
		
		alMailData = new ArrayList<MailData>(); 
		
		listAdapter = new MailListAdapter(this, R.layout.list_maillist_inbox, alMailData);
		lvMailList = (ListView)findViewById(R.id.maillistListView);
		lvMailList.setAdapter(listAdapter);
		lvMailList.setOnItemClickListener(mItemClickListener);

		//[131021]이메일 서비스 추가. 계정 데이터를 set 해주어야 한다.
		Intent serviceIntent = new Intent(this, EmailService.class);
		startService(serviceIntent);
		
		fullSync();

		
	}
	
	@Override
	public void onBackPressed() {
//		taskFullSync.cancel(true);
		super.onBackPressed();
	}
	
	
	@Override
	protected void onDestroy() {
//		taskFullSync.cancel(true);
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.mail_list, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int nSelect = item.getItemId();
		
		switch(nSelect) {
		case R.id.maillistMenuFullsync:
			fullSync();
			break;
		case R.id.maillistMenuWrite:
			Intent composerIntent = new Intent(MailListActivity.this, ComposerActivity.class);
			composerIntent.putExtra("ID", sID);
			composerIntent.putExtra("password", sPassword);
			composerIntent.putExtra("host", sHost);
//			composerIntent.putExtra("from", sID);
			startActivity(composerIntent);
			break;
		case R.id.maillistMenuDelete:
			Builder digDeleteSub = new AlertDialog.Builder(MailListActivity.this);
			digDeleteSub.setMessage("Delete Account?").setPositiveButton("Yes", new DialogInterface.OnClickListener() {				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					//TODO 계정 삭제 작업 시작
					//task를 종료시킨다
					if (taskFullSync != null) {
						taskFullSync.cancel(true);
						
					}
					
					//mail DB를 지운다
					//account DB를 지운다
					SharedPreferences.Editor editor = accountInfo.edit();
					editor.remove("exist_account");
					editor.remove("password");
					editor.commit();
					
					Intent welcomeIntent = new Intent(MailListActivity.this, Welcome.class);
					startActivity(welcomeIntent);
					
					finish();
				}
			}).setNegativeButton("No", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
				}
			})
			.show();
			break;
		}
		return super.onOptionsItemSelected(item);
	}
	
	
	public void fullSync(){ //TODO 아직 fullsync의 역할을 수행하고 있지는 않음.
//		alMailData.clear();
//		mHandler.sendEmptyMessage(0);
		
		SQLiteDatabase DBMessage = (new EmailDBHelper(this)).getReadableDatabase();
		Cursor csMailData = DBMessage.rawQuery("SELECT uid, sender, receiver, cc, bcc, subject, date, contents FROM messages ORDER BY uid DESC", null);
		while (csMailData.moveToNext()) {
			MailData md = new MailData();
			md.setUID(csMailData.getInt(0));
			md.setFromData(csMailData.getString(1));
			md.setToData(csMailData.getString(2));
			md.setCCData(csMailData.getString(3));
			md.setBCCData(csMailData.getString(4));
			md.setMailSubject(csMailData.getString(5));
			md.setMailDate(csMailData.getString(6));
			md.setContents(csMailData.getString(7));
			
			alMailData.add(md);
			mHandler.sendEmptyMessage(0);
		}
		csMailData.close();
		//여기서 검색을 통해 기존에 있으면 집어넣지 않는다
		DBMessage.close();
		
//		//[131021]email service를 위해 잠시 block
//		if (taskFullSync != null) {
//			taskFullSync.cancel(true);
//		}
//		taskFullSync = new FullSyncTask();
//		taskFullSync.execute();
	}
	
	
	class FullSyncTask extends AsyncTask<Void, Void, Boolean> {
		
		boolean bSuccessAccess = false;
		int nMsgCount = 0;
		Message[] mails;
		
		int nMailToRoad = 0; //이 숫자 까지의 인덱스의 메일만 읽어오도록 한다.
		
		@Override
		protected Boolean doInBackground(Void... params) {
			//[130903] mutex 아닌 동기회 방법. 이후 동기화 기법을 사용하도록 한다. 
			bNowSync = true;
			Log.d(sTag, "FullSync Start");
			
			alMailData.clear();
			mHandler.sendEmptyMessage(0);
			try {
				//세션을 만들고 접근을 시도한 다음
//				loginSession = new IMAP(sHost, sID, sPassword);
				//[130828] changed by singleton parttern using [start]
				loginSession = IMAP.getInstance();
				loginSession.initIMAP(sHost, sID, sPassword);
				//[130828] changed by singleton parttern using [end]
				loginSession.open();
				
				loginSession.getMessages(alMailData, mHandler);
				//folder를 미리 얻어준다. 이는 디테일뷰로 넘길 때 사용된다.
				folder = loginSession.getFolder();
				Log.d(sTag, "get data of messages, message count = " + alMailData.size());
			} catch (NoSuchProviderException e) {
				Log.e(sTag, "NoSuchProviderException");
				sErrorMsg = "(NoSuchProviderException)";
				bSuccessAccess = false;
				e.printStackTrace();
			} catch (MessagingException e) {
				Log.e(sTag, "MessagingException");
				sErrorMsg = "(MessagingException)";
				bSuccessAccess = false;
				e.printStackTrace();
			} finally {
				//TODO 수정하여야 함
//				endSession();
				bNowSync = false;
				Log.d(sTag, "FullSync have Finished");
			}
			return bSuccessAccess;
		}
		
		public void endSession(){
			try {
				loginSession.close();
				
			} catch (MessagingException e) {
				Log.e(sTag, "MessagingException in EndSession");
				sErrorMsg = "(MessagingException)";
				bSuccessAccess = false;
				e.printStackTrace();
			}
		}
		
		public void parseContent(Part msg, MailData md) throws IOException, MessagingException{
			//TODO [130816] 이 부분은 재귀적으로 메일 내용을 읽어 와야함. 추후 구현 예정
			boolean haveAttach = false;
			if(msg.isMimeType("multipart/*")) {
				
				Multipart multipart = (Multipart)msg.getContent();
				for(int partIndex = 0; partIndex < multipart.getCount(); partIndex++) {
					Part part = multipart.getBodyPart(partIndex);

					parseContent(part, md);
				}
			} else if (msg.isMimeType("text/plain")) {
				
				String str = MimeUtility.decodeText(msg.getContent().toString());
				Log.d(sTag, "text/plain case convert before : " + str);
//				md.setContents(new String(str.getBytes("EUC-KR"), "UTF-8"));
				md.setContents(str);
				Log.d(sTag, "text/plain case convert after : " + md.getContents());
				//TODO
			} else if (msg.isMimeType("text/html")) {
				String str = MimeUtility.decodeText(msg.getContent().toString());
				Log.d(sTag, "text/html case convert before : " + str);
//				md.setContents(new String(str.getBytes("EUC-KR"), "UTF-8"));
				md.setContents(str);
				Log.d(sTag, "text/html case convert after : " + md.getContents());
				//TODO
			} else {
				haveAttach = true;
				md.setContents(md.getContents() + "[ATTACHMENT]");
			}
			
			if(haveAttach) {
				String disposiotion = msg.getDisposition();
				
				if(disposiotion == null || Part.ATTACHMENT.equalsIgnoreCase(disposiotion)) {
					String filename = msg.getFileName();
					md.addAttachFileName(filename);
				}
			}
		}
	}
}

class MailListAdapter extends BaseAdapter {
	Context context;
	LayoutInflater Inflater;
	ArrayList<MailData> maildata;
	int layout;
	
	public MailListAdapter(Context _context, int _layout, ArrayList<MailData> _maildata){
		context = _context;
		Inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		maildata = _maildata;
		layout = _layout;
	}
	
	
	@Override
	public int getCount() {
		return maildata.size();
	}

	@Override
	public Object getItem(int position) {
		return maildata.get(position).getMailSubject();
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		final int pos = position;

		if (convertView == null) {
			convertView = Inflater.inflate(layout, parent, false);
		}
		TextView tvFrom = (TextView)convertView.findViewById(R.id.listFrom); //*******************************************************여기 잘못됨
		TextView tvData = (TextView)convertView.findViewById(R.id.listDate);
		TextView tvSubject = (TextView)convertView.findViewById(R.id.listSubject);
		
		tvFrom.setText(maildata.get(position).getFromData());
		tvData.setText(maildata.get(position).getMailDate());
		tvSubject.setText(maildata.get(position).getMailSubject());
		
		return convertView;
	}
}
